import { _decorator, Color, Component, Graphics, instantiate, Label, NodeEventType, Sprite } from 'cc';
import { findDiamondRoad } from './ThetaStar';
const { ccclass, property } = _decorator;

/** 按钮事件类型 */
enum clickType {
    /** 障碍 */
    block,
    /** 起点 */
    start,
    /** 终点 */
    end,
    /** 路 */
    road
}

@ccclass('main')
export class main extends Component {
    /** 地图 */
    map: any
    /** 移动路径 */
    path: any
    /** 起点 */
    startPos: any
    /** 终点 */
    endPos: any
    type: clickType = clickType.start
    start() {

        this.initMap()
        this.init()
        this.findRoad()
        this.render()

        for (const key in clickType) {
            this.node.getChildByName('btn' + key)?.on(NodeEventType.TOUCH_END, () => {
                this.type = Number(key) as any
                this.render()
            })
        }
    }

    init(): void {
        
        const diamond = this.node.getChildByName('diamond')
        const stage = this.node.getChildByName('stage')

        for (let i = 0; i < this.map.length; i++) {
            for (let j = 0; j < this.map[i].length; j++) {
                const x = (j * 80) + ((i % 2) * 40)
                const y = i * 20
                const node = instantiate(diamond)
                node.name = i + '-' + j
                node.parent = stage
                node.setPosition(x, y)
                node.on(NodeEventType.TOUCH_END, () => {
                    this.onClickBlock(i, j)
                })
            }
        }
    }
    /** 查询可移动路径 */
    findRoad() {
        this.path = findDiamondRoad(this.map, this.startPos, this.endPos)
    }

    /** 渲染页面 */
    render() {
        const stage = this.node.getChildByName('stage')

        for (let i = 0; i < this.map.length; i++) {
            for (let j = 0; j < this.map[i].length; j++) {
                const node = stage.getChildByName(i + '-' + j)
                if (this.map[i][j] == 0) {
                    node.getComponent(Sprite).color = Color.BLACK
                } else {
                    node.getComponent(Sprite).color = Color.GREEN
                }
                node.getChildByName('lab').getComponent(Label).string = i + '-' + j
            }
        }

        const gs = this.node.getChildByName('gs').getComponent(Graphics)
        gs.clear()


        const i = this.startPos[0]
        const j = this.startPos[1]
        const x = (j * 80) + ((i % 2) * 40)
        const y = i * 20
        gs.moveTo(x, y)

        for (const pos of this.path) {
            const i = pos[0]
            const j = pos[1]
            const x = (j * 80) + ((i % 2) * 40)
            const y = i * 20
            gs.lineTo(x, y)
            const node = stage.getChildByName(i + '-' + j)
            node.getComponent(Sprite).color = Color.RED
        }

        gs.strokeColor = Color.BLUE
        gs.lineWidth = 8
        gs.stroke()

        stage.getChildByName(this.startPos[0] + '-' + this.startPos[1])
            .getComponent(Sprite).color = Color.YELLOW
        stage.getChildByName(this.endPos[0] + '-' + this.endPos[1])
            .getComponent(Sprite).color = Color.WHITE

        let str = ''
        switch (this.type) {
            case clickType.start:
                str = '点击设置起点'
                break;
            case clickType.end:
                str = '点击设置终点'
                break;
            case clickType.road:
                str = '点击设置路'
                break;
            case clickType.block:
                str = '点击设置障碍'
                break;
        }

        this.node.getChildByName('desc').getComponent(Label).string = str
    }

    /** 初始化地图 */
    initMap() {
        
        this.startPos = [2, 1]
        this.endPos = [29, 5]
        this.map = []
        for (let i = 0; i < 30; i++) {
            this.map[i] = []
            for (let j = 0; j < 8; j++) {
                this.map[i].push(1)
            }
        }

        this.setBlock(3, 0)
        this.setBlock(3, 1)
        this.setBlock(2, 2)
        this.setBlock(2, 4)
        this.setBlock(3, 3)
        this.setBlock(4, 3)
        this.setBlock(6, 2)
        this.setBlock(5, 2)
        this.setBlock(6, 1)
        this.setBlock(7, 1)
        this.setBlock(8, 1)

        this.setBlock(0, 6)
        this.setBlock(2, 6)
        this.setBlock(3, 4)
        this.setBlock(5, 6)
        this.setBlock(6, 6)
        this.setBlock(4, 7)
        this.setBlock(4, 5)
        this.setBlock(5, 5)


        this.setBlock(13, 0)
        this.setBlock(12, 1)
        this.setBlock(11, 1)
        this.setBlock(10, 2)
        this.setBlock(25, 2)
        this.setBlock(22, 1)

        this.setBlock(23, 1)
        this.setBlock(23, 2)
        this.setBlock(8, 3)
        this.setBlock(7, 3)
        this.setBlock(6, 4)
        this.setBlock(7, 4)
        this.setBlock(8, 5)

        this.setBlock(7, 7)
        this.setBlock(8, 7)

        this.setBlock(11, 5)
        this.setBlock(9, 6)
        this.setBlock(10, 6)

        this.setBlock(11, 3)
        this.setBlock(12, 4)
        this.setBlock(14, 4)
        this.setBlock(16, 4)
        this.setBlock(18, 4)
        this.setBlock(20, 4)
        this.setBlock(22, 4)
        this.setBlock(24, 4)
        this.setBlock(26, 4)
        this.setBlock(28, 4)

        this.setBlock(15, 4)
        this.setBlock(15, 5)
        this.setBlock(15, 6)
        this.setBlock(17, 7)
        this.setBlock(18, 7)
        this.setBlock(18, 6)
        this.setBlock(24, 5)
        this.setBlock(23, 5)
        this.setBlock(22, 6)
        this.setBlock(26, 6)
        this.setBlock(27, 5)
        this.setBlock(12, 2)
        this.setBlock(16, 2)
        this.setBlock(16, 3)
        this.setBlock(13, 2)
        this.setBlock(17, 1)
        this.setBlock(18, 1)
    }

    /** 设置障碍 */
    setBlock(i: number, j: number) {
        this.map[i][j] = 0
    }

    /** 点击菱形事件 */
    onClickBlock(i: number, j: number) {

        switch (this.type) {
            case clickType.start:
                this.startPos = [i, j]
                break;
            case clickType.end:
                this.endPos = [i, j]
                break;
            case clickType.road:
                this.map[i][j] = 1
                break;
            case clickType.block:
                this.map[i][j] = 0
                break;
        }

        this.findRoad()
        this.render()
    }
}